// 导入本地模块
const path = require('path');
const { customRequire } = require('../utils.js');
const config = require('../config');
const manifest = require('../manifest.json');
const { log, error, cleanupModuleData } = require('../utils.js');
const { formatDateToEnglish } = require('../utils/dateFormatter.js');
const pathUtils = require('../utils/path-utils');

// 设置全局错误处理器
process.on('uncaughtException', (err) => {
    console.error('未捕获的异常:', err);
    console.error('错误堆栈:', err.stack);
    error('未捕获的异常: ' + err.message, err);
    log('发生未捕获的异常: ' + err.message);
});

process.on('unhandledRejection', (reason, promise) => {
    console.error('未处理的Promise拒绝:', reason);
    if (reason instanceof Error) {
        console.error('错误堆栈:', reason.stack);
        error('未处理的Promise拒绝: ' + reason.message, reason);
        log('发生未处理的Promise拒绝: ' + reason.message);
    } else {
        error('未处理的Promise拒绝: ' + reason);
        log('发生未处理的Promise拒绝: ' + reason);
    }
});

// 导入外部模块
console.log('正在导入playwright模块...');
log('正在导入playwright模块...');
const { chromium } = customRequire('playwright');
console.log('正在导入fs模块...');
log('正在导入fs模块...');
const fs = require('fs');

// 记录配置信息
log(`插件版本: ${manifest.version}`);
log(`配置加载完成: 浏览器超时=${config.browser.timeout}ms, 重试次数=${config.retry.maxRetries}`);
log(`目标网站: ${config.website.url}, 时间框架: ${config.website.timeframe}`);

// 定义需要匹配的CFR范围
const targetRanges = [
  { title: 16, parts: ['300-323', '423', '500-503', '1000+'] },
  { title: 21, parts: ['800-898'] },
  { title: 49, parts: ['500-599'] },
  { title: 10, parts: ['429'] },
  { title: 19, parts: ['134.0-134.55'] },
  { title: 47, parts: ['15.1-15.717'] }
];

// 检查part号码是否在指定范围内
function isPartInRange(partText, targetParts) {
  console.log(`    检查Part文本: "${partText}" 是否匹配范围: [${targetParts.join(', ')}]`);
  
  // 提取Part号码
  const partMatch = partText.match(/Part\s+(\d+(?:\.\d+)?)/i) || partText.match(/(\d+(?:\.\d+)?)/);
  if (!partMatch) {
    console.log(`    无法从"${partText}"中提取Part号码`);
    return false;
  }
  
  const partNum = parseFloat(partMatch[1]);
  console.log(`    提取的Part号码: ${partNum}`);
  
  for (const range of targetParts) {
    console.log(`    检查范围: ${range}`);
    
    if (range.includes('+')) {
      // 处理1000+这种情况
      const baseNum = parseInt(range.replace('+', ''));
      if (partNum >= baseNum) {
        console.log(`    ✓ 匹配 ${range}: ${partNum} >= ${baseNum}`);
        return true;
      }
    } else if (range.includes('-')) {
      // 处理范围情况如300-323
      const [start, end] = range.split('-').map(s => parseFloat(s));
      if (partNum >= start && partNum <= end) {
        console.log(`    ✓ 匹配 ${range}: ${start} <= ${partNum} <= ${end}`);
        return true;
      }
    } else {
      // 处理单个数字情况
      const targetNum = parseFloat(range);
      if (partNum === targetNum) {
        console.log(`    ✓ 匹配 ${range}: ${partNum} === ${targetNum}`);
        return true;
      }
    }
  }
  
  console.log(`    ✗ 不匹配任何范围`);
  return false;
}

// 日期格式转换函数
function formatDate(dateString) {
  // 使用新的日期格式转换工具
  return formatDateToEnglish(dateString);
}

// 全局变量，用于存储当前浏览器实例，以便在中断时关闭
let currentBrowser = null;

async function scrapeCFRParts(isHeadless, signal) {
  // 记录开始信息
  log(`开始执行 CFR Parts 数据抓取任务`, 'info');
  log(`目标范围: ${targetRanges.length} 个 Title 类别`, 'info');
  
  // 检查是否已经被中止
  if (signal && signal.aborted) {
    console.log('任务已被取消，不启动浏览器');
    log('任务已被用户取消', 'warning');
    throw new Error('任务已被用户取消');
  }
  
  console.log('启动浏览器...');
  log('启动浏览器...');
  log('浏览器配置: ' + (isHeadless ? '无头模式' : '有界面模式') + ', 超时: ' + config.browser.timeout + 'ms');
  const browser = await chromium.launch({ 
    headless: !isHeadless, // 反转isHeadless参数，使其与info-update.js中的提示保持一致
    timeout: config.browser.timeout,
    args: ['--start-maximized', '--disable-features=IsolateOrigins,site-per-process'],
    executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
  });
  log('浏览器启动成功，使用' + (isHeadless ? '无头模式' : '有界面模式'));
  
  // 存储浏览器实例，以便在中断时关闭
  currentBrowser = browser;
  
  // 如果信号存在，添加中断处理
  if (signal) {
    log('已设置中断信号处理器', 'info');
    signal.addEventListener('abort', async () => {
      console.log('收到中断信号，正在关闭浏览器...');
      log('收到中断信号，正在关闭浏览器...', 'warning');
      if (currentBrowser) {
        try {
          await currentBrowser.close();
          console.log('浏览器已关闭（由中断信号触发）');
          log('浏览器已关闭（由中断信号触发）', 'info');
        } catch (err) {
          console.error('关闭浏览器时出错:', err);
          log(`关闭浏览器时出错: ${err.message}`, 'error');
        }
        currentBrowser = null;
      }
    });
  }
  const context = await browser.newContext({ viewport: null, userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' });
  log('创建浏览器上下文成功', 'info');
  const page = await context.newPage();
  log('创建新页面成功', 'info');
  
  // 设置默认超时时间
  page.setDefaultTimeout(config.browser.defaultTimeout);
  log(`设置页面默认超时时间: ${config.browser.defaultTimeout}ms`, 'info');
  
  // 创建数组来收集所有数据
  const allData = [];
  
  try {
    console.log('访问网站...');
    log('开始访问目标网站...');
    
    // 监听页面错误
    page.on('pageerror', err => {
      console.error('页面错误:', err.message);
      error(`页面错误: ${err.message}`, err);
      log(`检测到页面JavaScript错误: ${err.message}`);
    });
    
    // 监听请求失败
    page.on('requestfailed', request => {
      const failure = request.failure();
      const url = request.url();
      console.error(`请求失败: ${url} - ${failure?.errorText || 'Unknown error'}`);
      error(`请求失败: ${url} - ${failure?.errorText || 'Unknown error'}`);
      log(`网络请求失败: ${url.substring(0, 50)}... - ${failure?.errorText || 'Unknown error'}`, 'error');
    });
    
    console.log(`正在导航到 ${config.website.url}...`);
    log(`正在导航到目标网站: ${config.website.url}...`);
    log(`页面加载超时设置: ${config.browser.pageLoadTimeout}ms`);
    try {
      await page.goto(config.website.url, {
        waitUntil: 'networkidle', // 等待网络空闲
        timeout: config.browser.pageLoadTimeout
      });
      console.log('页面导航成功');
      log('页面导航成功，网站已加载');
    } catch (navigationError) {
      console.error(`页面导航失败: ${navigationError.message}`);
      error(`页面导航失败: ${navigationError.message}`, navigationError);
      
      // 尝试重新导航，使用不同的等待策略
      console.log('尝试使用不同的等待策略重新导航...');
      log('首次导航失败，尝试使用不同的等待策略重新导航...', 'warning');
      log(`使用 'load' 事件等待策略，超时时间增加到: ${config.browser.pageLoadTimeout * 1.5}ms`, 'info');
      await page.goto(config.website.url, {
        waitUntil: 'load', // 只等待 load 事件
        timeout: config.browser.pageLoadTimeout * 1.5 // 增加超时时间
      });
      log('使用备用策略导航成功', 'success');
    }
     
     console.log('等待页面完全加载...');
     log('等待页面完全加载...');
     log('等待页面主要内容元素 #timeframeBrowse 出现，超时: 20000ms');
     // 等待页面主要内容加载
     await page.waitForSelector('#timeframeBrowse', { timeout: 20000 });
     log('页面主要内容已加载完成');
     
     // 额外等待确保所有元素都已渲染
     await page.waitForTimeout(3000);
     
     /**
      * 根据时间框架值生成对应的label选择器
      * @param {string} timeframe - 时间框架值，如 'Past 7 Days'
      * @returns {string} - 对应的label选择器
      */
     function getTimeframeLabelSelector(timeframe) {
       // 直接映射到对应的label选择器
       if (timeframe === 'Past 24 Hours') {
         return 'label[for="timeframeOptions1"]';
       } else if (timeframe === 'Past 7 Days') {
         return 'label[for="timeframeOptions2"]';
       } else if (timeframe === 'Past 30 Days') {
         return 'label[for="timeframeOptions3"]';
       } else if (timeframe === 'Past 180 Days') {
         return 'label[for="timeframeOptions4"]';
       } else if (timeframe === 'Past 365 Days') {
         return 'label[for="timeframeOptions5"]';
       }
       
       // 默认返回Past 7 Days的选择器
       return 'label[for="timeframeOptions2"]';
     }
     
     // 使用简化的选择器策略来找到时间框架选项
     console.log('查找时间框架选项...');
     const timeframeSelector = getTimeframeLabelSelector(config.website.timeframe);
     console.log(`使用选择器: ${timeframeSelector}`);
     
     let timeframeElement = null;
     try {
       await page.waitForSelector(timeframeSelector, { timeout: config.waitTimes.selectorTimeout, visible: true });
       timeframeElement = await page.$(timeframeSelector);
       
       if (timeframeElement) {
         const isVisible = await timeframeElement.isVisible();
         const boundingBox = await timeframeElement.boundingBox();
         if (isVisible && boundingBox) {
           console.log(`找到可见的时间框架选项: ${timeframeSelector}`);
         } else {
           timeframeElement = null;
         }
       }
     } catch (e) {
       console.log(`选择器 ${timeframeSelector} 未找到或不可见: ${e.message}`);
     }
     
     if (!timeframeElement) {
       throw new Error(`无法找到"${config.website.timeframe}"时间框架选项，使用选择器: ${timeframeSelector}`);
     }
     
     console.log(`选择${config.website.timeframe}时间段...`);
     log(`选择时间框架: ${config.website.timeframe}`);
     log('尝试点击时间框架选项...');
     
     // 记录当前使用的选择器
     log(`使用的选择器: ${timeframeSelector}`, 'info');
     
     // 尝试多种点击方式
     let clickSuccess = false;
     
     // 方法1: 直接点击元素
     try {
       await timeframeElement.click();
       clickSuccess = true;
       console.log('直接点击成功');
       log('直接点击时间框架选项成功', 'success');
     } catch (e) {
       console.log('直接点击失败，尝试其他方法');
       log(`直接点击失败: ${e.message}，尝试其他方法`, 'warning');
     }
     
     // 方法2: 使用JavaScript点击
     if (!clickSuccess) {
       try {
         await page.evaluate((element) => {
           element.click();
         }, timeframeElement);
         clickSuccess = true;
         console.log('JavaScript点击成功');
         log('JavaScript点击时间框架选项成功', 'success');
       } catch (e) {
         console.log('JavaScript点击失败');
         log(`JavaScript点击失败: ${e.message}`, 'warning');
       }
     }
     
     // 方法3: 尝试查找与时间框架值匹配的input元素
     if (!clickSuccess) {
       try {
         const result = await page.evaluate((timeframe) => {
           // 尝试查找与时间框架值匹配的input元素
           const inputs = Array.from(document.querySelectorAll('input[type="radio"][name="timeframeOptions"]'));
           console.log(`页面上找到 ${inputs.length} 个时间框架选项`);
           
           // 精确匹配时间框架值
           let targetInput = inputs.find(input => input.value === timeframe);
           
           if (!targetInput) {
             // 如果精确匹配失败，尝试根据时间框架映射到对应的ID
             const timeframeIdMap = {
               'Past 24 Hours': 'timeframeOptions1',
               'Past 7 Days': 'timeframeOptions2',
               'Past 30 Days': 'timeframeOptions3',
               'Past 180 Days': 'timeframeOptions4',
               'Past 365 Days': 'timeframeOptions5'
             };
             
             const targetId = timeframeIdMap[timeframe];
             if (targetId) {
               targetInput = document.querySelector(`#${targetId}`);
               console.log(`通过ID映射找到时间框架选项: ${targetId}`);
             }
           }
           
           if (targetInput) {
             targetInput.checked = true;
             targetInput.dispatchEvent(new Event('change', { bubbles: true }));
             targetInput.dispatchEvent(new Event('click', { bubbles: true }));
             console.log(`成功选中时间框架: ${targetInput.id} (${targetInput.value})`);
             return { success: true, selectedId: targetInput.id, selectedValue: targetInput.value };
           }
           
           // 如果仍然找不到，记录可用选项
           const availableOptions = inputs.map(input => ({ id: input.id, value: input.value }));
           console.log('可用的时间框架选项:', availableOptions);
           
           return { success: false, availableOptions };
         }, config.website.timeframe);
         
         if (result.success) {
           clickSuccess = true;
           console.log(`直接设置input成功: ${result.selectedId} (${result.selectedValue})`);
           log(`直接设置时间框架input成功: ${result.selectedId} (${result.selectedValue})`, 'success');
         } else {
           console.log('直接设置input失败，可用选项:', result.availableOptions);
           log(`直接设置input失败，可用选项: ${JSON.stringify(result.availableOptions)}`, 'warning');
         }
       } catch (e) {
         console.log('直接设置input失败:', e.message);
         log(`直接设置input失败: ${e.message}`, 'warning');
       }
     }
     
     if (!clickSuccess) {
       const errorMsg = `所有点击方法都失败了，无法选择时间框架: ${config.website.timeframe}`;
       log(errorMsg, 'error');
       // 尝试获取页面上可用的时间框架选项
       try {
         const availableOptions = await page.evaluate(() => {
           const inputs = Array.from(document.querySelectorAll('input[type="radio"]'));
           return inputs.map(input => ({ id: input.id, value: input.value, name: input.name }));
         });
         log(`页面上可用的时间框架选项: ${JSON.stringify(availableOptions)}`, 'info');
       } catch (e) {
         log(`无法获取页面上的时间框架选项: ${e.message}`, 'warning');
       }
       throw new Error(errorMsg);
     }
     
     log('时间框架选择成功');
     log(`等待选择生效，等待时间: ${config.waitTimes.afterSelection}ms`);
     
     // 等待一下确保选择生效
     await page.waitForTimeout(config.waitTimes.afterSelection);
     log('等待选择生效...');
    
    // 查找并点击Submit按钮
     console.log('查找Submit按钮...');
     const submitSelectors = config.selectors.submitButtons;
     
     let submitClicked = false;
     for (const selector of submitSelectors) {
       try {
         const element = await page.$(selector);
         if (element && await element.isVisible()) {
           console.log(`点击Submit按钮: ${selector}`);
           await element.click();
           submitClicked = true;
           break;
         }
       } catch (e) {
         if (config.debug.verboseLogging) {
           console.log(`Submit按钮选择器 ${selector} 失败`);
         }
       }
     }
     
     if (!submitClicked) {
       const errorMsg = '无法找到或点击Submit按钮';
       log(errorMsg);
       throw new Error(errorMsg);
     }
     
     log('Submit按钮点击成功');
     log(`等待搜索结果加载，超时: ${config.browser.defaultTimeout}ms`);
     
     // 等待搜索结果加载
     console.log('等待搜索结果...');
     log('等待搜索结果加载...');
     await page.waitForSelector(config.selectors.resultsContainer, { 
       timeout: config.browser.defaultTimeout 
     });
     log('搜索结果已加载');
     
     // 等待内容完全加载
     await page.waitForTimeout(config.waitTimes.afterSubmit);
    
    console.log('开始搜索匹配的Title...');
    log('开始搜索匹配的Title...');
    log(`需要搜索的Title数量: ${targetRanges.length}`);
    const results = [];
    
    // 遍历目标Title
    for (const target of targetRanges) {
      console.log(`检查Title ${target.title}...`);
      log(`检查Title ${target.title}...`, 'info');
      log(`目标Parts范围: ${target.parts.join(', ')}`, 'info');
      
      // 查找对应的Title面板
      const titleSelector = `[data-browsepath="${target.title}"]`;
      const titleElement = await page.$(titleSelector);
      
      if (titleElement) {
        console.log(`找到Title ${target.title}，点击展开...`);
        log(`找到Title ${target.title}，点击展开...`, 'info');
        
        // 点击展开Title
        await titleElement.click();
        
        // 等待内容加载
        await page.waitForTimeout(2000);
        
        // 查找该Title下的所有Part
        const collapseId = `#collapseOne${await titleElement.getAttribute('id')}`;
        const partsContainer = await page.$(collapseId);
        
        console.log(`  Title ${target.title} 面板已展开，查找Part链接...`);
        
        // 等待内容完全加载
        await page.waitForTimeout(2000);
        
        // 查找该Title下的所有Part面板 - Part信息在panel-heading中
        const partPanels = await page.$$(`[data-browsepath^="${target.title}/"]`);
        
        console.log(`  找到 ${partPanels.length} 个Part面板`);
        
        for (const partPanel of partPanels) {
          const browsePath = await partPanel.getAttribute('data-browsepath');
          const partSpan = await partPanel.$('span[aria-expanded]');
          
          if (partSpan) {
            const partText = await partSpan.textContent();
            console.log(`  检查Part: "${partText.trim()}" (路径: ${browsePath})`);
            
            // 检查是否在目标范围内
             if (partText && isPartInRange(partText, target.parts)) {
               console.log(`  ✓ 匹配: ${partText.trim()}`);
               log(`找到匹配的Part: ${partText.trim()}`, 'success');
               
               // 点击Part展开内容
               console.log(`    点击Part ${partText.trim()}展开内容...`);
               log(`点击展开Part ${partText.trim()}内容...`, 'info');
               await partPanel.click();
               
               // 等待loading指示器消失
               log(`Waiting for content of Part ${partText.trim()} to load...`, 'info');
               await page.waitForSelector('#loadgraphicoverlay', { state: 'hidden', timeout: 30000 });
               log(`Content of Part ${partText.trim()} loaded.`, 'success');
               
               // 查找该Part的collapse容器
               const partId = await partPanel.getAttribute('id');
               const collapseSelector = `#collapseOne${partId}`;
               const partCollapseContainer = await page.$(collapseSelector);
               
               // 初始化标题变量，确保在所有情况下都有定义
               let titleText = "";
               
               if (partCollapseContainer) {
                 console.log(`    Part ${partText.trim()}内容已展开，提取标题信息...`);
                 
                 // 提取标题信息
                  try {
                    // 尝试获取标题文本 - 使用多种选择器
                    const selectors = [
                      'tr:nth-child(2) td p b',  // 第二行的td中的p中的b元素（用户指定的位置）
                      'tr:nth-child(2) td p',   // 第二行的td中的p元素
                      'tr:nth-child(2) td',     // 第二行的td元素
                      'p > b',                  // 通常在p标签中的b标签内
                      'td p',                   // 表格单元格中的段落
                      'p',                      // 任何段落
                      'td',                     // 任何表格单元格
                      '.title',                 // 带有title类的元素
                      'div > p:first-child',    // div中的第一个段落
                      'h1, h2, h3, h4, h5'      // 任何标题元素
                    ];
                    
                    // 尝试每个选择器
                    for (const selector of selectors) {
                      const element = await partCollapseContainer.$(selector);
                      if (element) {
                        const text = await element.textContent();
                        if (text && text.trim()) {
                          titleText = text.trim();
                          console.log(`    提取到标题 [${selector}]: ${titleText}`);
                          log(`提取到标题 [${selector}]: ${titleText}`, 'info');
                          break;
                        }
                      }
                    }
                    
                    // 如果没有找到标题，尝试获取整个容器的文本并提取第一行
                    if (!titleText) {
                      const containerText = await partCollapseContainer.textContent();
                      if (containerText) {
                        const lines = containerText.split('\n')
                          .map(line => line.trim())
                          .filter(line => line.length > 0);
                        
                        if (lines.length > 0) {
                          titleText = lines[0];
                          console.log(`    提取到标题(容器文本): ${titleText}`);
                          log(`提取到标题(容器文本): ${titleText}`, 'info');
                        }
                      }
                    }
                  } catch (e) {
                    console.log(`    提取标题失败: ${e.message}`);
                    log(`提取标题失败: ${e.message}`, 'warning');
                  }
                 
                 console.log(`    Part ${partText.trim()}内容已展开，查找TEXT按钮...`);
                 
                 // 查找所有TEXT按钮 - 尝试多种选择器
                  let textButtons = await partCollapseContainer.$$('button');
                  if (textButtons.length === 0) {
                    textButtons = await partCollapseContainer.$$('a');
                  }
                  if (textButtons.length === 0) {
                    textButtons = await partCollapseContainer.$$('[title*="text"], [alt*="text"]');
                  }
                  
                  // 过滤包含TEXT字样的按钮
                  const filteredTextButtons = [];
                  for (const button of textButtons) {
                    const buttonText = await button.textContent();
                    const title = await button.getAttribute('title');
                    const alt = await button.getAttribute('alt');
                    
                    if ((buttonText && buttonText.toLowerCase().includes('text')) ||
                        (title && title.toLowerCase().includes('text')) ||
                        (alt && alt.toLowerCase().includes('text'))) {
                      filteredTextButtons.push(button);
                    }
                  }
                  
                  console.log(`    找到 ${filteredTextButtons.length} 个TEXT按钮`);
                  
                  for (let i = 0; i < filteredTextButtons.length; i++) {
                    const textButton = filteredTextButtons[i];
                    console.log(`    点击第 ${i + 1} 个TEXT按钮...`);
                    
                    try {
                       // 获取点击前的页面数量
                       const pagesBefore = await context.pages();
                       const initialPageCount = pagesBefore.length;
                       console.log(`    点击前页面数量: ${initialPageCount}`);
                       
                       // 点击TEXT按钮
                       await textButton.click();
                       console.log(`    TEXT按钮已点击，等待新标签页...`);
                       
                       // 等待新页面出现
                       let newPage = null;
                       let attempts = 0;
                       const maxAttempts = 40; // 20秒，每次等待500ms
                       
                       while (attempts < maxAttempts && !newPage) {
                         await page.waitForTimeout(500);
                         const currentPages = await context.pages();
                         
                         if (currentPages.length > initialPageCount) {
                           // 找到新页面
                           newPage = currentPages[currentPages.length - 1];
                           console.log(`    检测到新页面，URL: ${newPage.url()}`);
                           break;
                         }
                         
                         attempts++;
                         if (attempts % 4 === 0) { // 每2秒打印一次
                           console.log(`    等待新页面... (${attempts * 0.5}秒)`);
                         }
                       }
                       
                       if (!newPage) {
                         log('新标签页打开超时', 'error');
                         throw new Error('新标签页打开超时');
                       }
                       log('新标签页成功打开', 'success');
                      
                      console.log(`新标签页已打开，等待内容加载...`);
                       await newPage.waitForTimeout(5000); // 等待内容加载
                       
                       // 获取页面内容
                       const textContent = await newPage.textContent('body');
                      
                      // 提取第一行数据中的日期和SUMMARY字段
                       // 获取第一行数据，形式如[Federal Register Volume 90, Number 126 (Thursday, July 3, 2025)]
                       const firstLineMatch = textContent.match(/^\[([^\]]+)\]/m);
                       // const firstLineMatch = textContent.match(/\[Federal Register.*?\((.+?)\)\]/i);
                       const dateInBrackets = firstLineMatch ? firstLineMatch[1].match(/\(([^\)]+)\)/) : null;
                       
                       // 提取SUMMARY和DATES字段
                       const summaryMatch = textContent.match(/SUMMARY:\s*([^\n]*(?:\n(?!\s*\n)[^\n]*)*)/i);
                       const datesMatch = textContent.match(/DATES:\s*([^\n]*(?:\n(?!\s*\n)[^\n]*)*)/i);
                      
                      // brief字段将在detail页面处理完成后赋值
                      
                      // 使用第一行中括号内的日期作为dates字段值
                      const dates = dateInBrackets ? dateInBrackets[1].trim() : '';
                      
                      console.log(`    提取的DATES: ${dates}`);
                      console.log(`    提取的SUMMARY: ${summaryMatch ? summaryMatch[1].substring(0, 100) : 'N/A'}...`);
                      log(`提取数据 - DATES: ${dates}`, 'info');
                      log(`提取数据 - SUMMARY: ${summaryMatch ? summaryMatch[1].substring(0, 50) : 'N/A'}...`, 'info');
                      
                      // 查找PDF按钮URL
                      let pdfUrl = '';
                      try {
                        // 回到原页面查找PDF按钮
                        const pdfButtons = await partCollapseContainer.$$('button, a');
                        for (const button of pdfButtons) {
                          const buttonText = await button.textContent();
                          const title = await button.getAttribute('title');
                          const alt = await button.getAttribute('alt');
                          const href = await button.getAttribute('href');
                          
                          if ((buttonText && buttonText.toLowerCase().includes('pdf')) ||
                              (title && title.toLowerCase().includes('pdf')) ||
                              (alt && alt.toLowerCase().includes('pdf'))) {
                            if (href) {
                              pdfUrl = href.startsWith('http') ? href : `https://www.govinfo.gov${href}`;
                            } else {
                              // 如果是button，可能需要点击获取URL
                              const onclick = await button.getAttribute('onclick');
                              if (onclick && onclick.includes('http')) {
                                const urlMatch = onclick.match(/https?:\/\/[^'"\s]+/);
                                if (urlMatch) {
                                  pdfUrl = urlMatch[0];
                                }
                              }
                            }
                            break;
                          }
                        }
                        console.log(`    找到PDF URL: ${pdfUrl}`);
                      } catch (pdfError) {
                        console.log(`    查找PDF按钮时出错: ${pdfError.message}`);
                      }
                      
                      // 获取standard值 - 点击DETAIL按钮
                      let standard = '';
                      let summaryContent = '';
                      try {
                        console.log(`    查找DETAIL按钮...`);
                        // 回到原页面查找DETAIL按钮
                        const detailButtons = await partCollapseContainer.$$('button, a');
                        let detailButton = null;
                        
                        for (const button of detailButtons) {
                          const buttonText = await button.textContent();
                          const title = await button.getAttribute('title');
                          const alt = await button.getAttribute('alt');
                          
                          if ((buttonText && buttonText.toLowerCase().includes('detail')) ||
                              (title && title.toLowerCase().includes('detail')) ||
                              (alt && alt.toLowerCase().includes('detail'))) {
                            detailButton = button;
                            break;
                          }
                        }
                        
                        if (detailButton) {
                          console.log(`    找到DETAIL按钮，准备点击...`);
                          
                          // 获取点击前的页面数量
                          const pagesBefore = await context.pages();
                          const initialPageCount = pagesBefore.length;
                          
                          // 点击DETAIL按钮 - 使用Ctrl+Click强制在新标签页打开
                          await detailButton.click({ modifiers: ['Control'] });
                          console.log(`    DETAIL按钮已点击（Ctrl+Click），等待新标签页...`);
                          
                          // 等待新页面出现
                          let detailPage = null;
                          let detailURL = '';
                          let attempts = 0;
                          const maxAttempts = 40;
                          
                          while (attempts < maxAttempts && !detailPage) {
                            await page.waitForTimeout(500);
                            const currentPages = await context.pages();
                            
                            if (currentPages.length > initialPageCount) {
                              detailPage = currentPages[currentPages.length - 1];
                              detailURL = detailPage.url();
                              console.log(`检测到DETAIL新页面，URL: ${detailURL}`);
                              break;
                            }
                            
                            attempts++;
                            if (attempts % 4 === 0) {
                              console.log(`    等待DETAIL新页面... (${attempts * 0.5}秒)`);
                            }
                          }
                          
                          if (detailPage) {
                            console.log(`    DETAIL新标签页已打开，等待内容加载...`);
                            try {
                              // 等待CFR Citation元素出现
                              await detailPage.waitForSelector('div[data-id="CFR Citation"]', { timeout: 10000 });
                              console.log('已定位到CFR Citations');
                              
                              // 使用JavaScript直接在页面中查找和获取内容
                              console.log(`查找CFR Citations元素的下一个同级div...`);
                              const jsResult = await detailPage.evaluate(() => {
                                // 查找CFR Citation元素
                                const citationElement = document.querySelector('div[data-id="CFR Citation"]');
                                if (!citationElement) {
                                  console.log('CFR Citation元素不存在');
                                  return { success: false, error: 'CFR Citation元素不存在' };
                                }
                                
                                console.log('找到CFR Citation元素:', citationElement.outerHTML.substring(0, 200));
                                
                                // 查找下一个同级元素
                                let nextSibling = citationElement.nextElementSibling;
                                
                                // 如果下一个同级元素不是div，继续查找
                                while (nextSibling && nextSibling.tagName.toLowerCase() !== 'div') {
                                  nextSibling = nextSibling.nextElementSibling;
                                }
                                
                                if (!nextSibling) {
                                  console.log('CFR Citations元素没有下一个div同级元素');
                                  return { success: false, error: 'CFR Citations元素没有下一个div同级元素' };
                                }
                                
                                console.log('找到下一个div同级元素:', nextSibling.outerHTML.substring(0, 200));
                                
                                // 获取文本内容，将<br>标签转换为空格
                                const html = nextSibling.innerHTML || '';
                                // 将<br>标签转换为空格，然后清理其他HTML标签
                                const textWithSpaces = html.replace(/<br\s*\/?>/gi, ' ')
                                                          .replace(/<[^>]*>/g, '')
                                                          .replace(/\s+/g, ' ')
                                                          .trim();
                                const cleanText = textWithSpaces;
                                
                                return { 
                                  success: true, 
                                  text: cleanText,
                                  tagName: nextSibling.tagName,
                                  className: nextSibling.className,
                                  id: nextSibling.id,
                                  html: nextSibling.outerHTML.substring(0, 500)
                                };
                              });
                              
                              console.log(`JavaScript获取结果:`, jsResult);
                              
                              if (jsResult.success) {
                                standard = jsResult.text;
                                console.log(`    成功获取standard值: ${standard}`);
                                log(`获取standard值: ${standard}`, 'success');
                                log(`元素信息 - 标签: ${jsResult.tagName}, 类名: ${jsResult.className}, ID: ${jsResult.id}`, 'info');
                                
                                // 提取Summary内容
                                console.log(`查找Summary元素的下一个同级div...`);
                                const summaryResult = await detailPage.evaluate(() => {
                                  // 查找Summary元素
                                  const summaryElement = document.querySelector('div[data-id="Summary"]');
                                  if (!summaryElement) {
                                    console.log('Summary元素不存在');
                                    return { success: false, error: 'Summary元素不存在' };
                                  }
                                  
                                  console.log('找到Summary元素:', summaryElement.outerHTML.substring(0, 200));
                                  
                                  // 查找下一个同级元素
                                  let nextSibling = summaryElement.nextElementSibling;
                                  
                                  // 如果下一个同级元素不是div，继续查找
                                  while (nextSibling && nextSibling.tagName.toLowerCase() !== 'div') {
                                    nextSibling = nextSibling.nextElementSibling;
                                  }
                                  
                                  if (!nextSibling) {
                                    console.log('Summary元素没有下一个div同级元素');
                                    return { success: false, error: 'Summary元素没有下一个div同级元素' };
                                  }
                                  
                                  console.log('找到Summary下一个div同级元素:', nextSibling.outerHTML.substring(0, 200));
                                  
                                  // 获取文本内容，将<br>标签转换为空格
                                  const html = nextSibling.innerHTML || '';
                                  // 将<br>标签转换为空格，然后清理其他HTML标签
                                  const textWithSpaces = html.replace(/<br\s*\/?>/gi, ' ')
                                                            .replace(/<[^>]*>/g, '')
                                                            .replace(/\s+/g, ' ')
                                                            .trim();
                                  const cleanText = textWithSpaces;
                                  
                                  return { 
                                    success: true, 
                                    text: cleanText,
                                    tagName: nextSibling.tagName,
                                    className: nextSibling.className,
                                    id: nextSibling.id,
                                    html: nextSibling.outerHTML.substring(0, 500)
                                  };
                                });
                                
                                console.log(`Summary JavaScript获取结果:`, summaryResult);
                                
                                if (summaryResult.success) {
                                  summaryContent = summaryResult.text;
                                  console.log(`    成功获取summaryContent值: ${summaryContent}`);
                                  log(`获取summaryContent值: ${summaryContent}`, 'success');
                                } else {
                                  console.log(`    获取summaryContent失败: ${summaryResult.error}`);
                                  log(`获取summaryContent失败: ${summaryResult.error}`, 'error');
                                }
                              } else {
                                console.log(`    获取standard值失败: ${jsResult.error}`);
                                log(`获取standard值失败: ${jsResult.error}`, 'warning');
                              }
                              

                            } catch (e) {
                              // 检查是否为超时错误
                              if (e.message && e.message.includes('Timeout')) {
                                console.log(`等待CFR Citation元素超时，可能页面上不存在该元素。`);
                                log(`等待CFR Citation元素超时，URL: ${detailURL}`, 'warning');
                              } else {
                                // 记录其他类型的错误
                                console.log(`    获取CFR Citation时出错: ${e.message}`);
                                log(`获取CFR Citation时出错: ${e.message}`, 'error');
                              }
                            }
                            
                            // 关闭DETAIL页面
                            await detailPage.close();
                            console.log(`    DETAIL页面已关闭`);
                          } else {
                            console.log(`    DETAIL新标签页打开超时`);
                            log('DETAIL新标签页打开超时', 'warning');
                          }
                        } else {
                          console.log(`    未找到DETAIL按钮`);
                          log('未找到DETAIL按钮', 'warning');
                        }
                      } catch (detailError) {
                        console.log(`    处理DETAIL按钮时出错: ${detailError.message}`);
                        log(`处理DETAIL按钮时出错: ${detailError.message}`, 'error');
                      }
                      
                      // 组合brief字段：将从detail页面提取的Summary内容与DATES字段组合
                      let brief = summaryContent || '';
                      if (datesMatch && datesMatch[1].trim()) {
                        brief = brief ? `${brief}\n\nDATES: ${datesMatch[1].trim()}` : `DATES: ${datesMatch[1].trim()}`;
                      }
                      console.log(`    组合后的brief字段: ${brief}`);
                      log(`组合brief字段完成，长度: ${brief.length}`, 'info');
                      
                      try {
                        // 创建JSON数据
                        const jsonData = {
                          region: "USA",
                          standard: standard,
                          standardName: titleText || '',
                          dateOfPublication: formatDate(dates) || '',
                          brief: brief || '',
                          url: pdfUrl || '',
                          // title: target.title,
                          // part: partText.replace(/[^\d]/g, ''),
                          // textIndex: i + 1,
                        };
                        
                        // 添加到数据数组
                        allData.push(jsonData);
                        console.log(`    数据已添加到集合中: Title ${target.title}, Part ${partText.replace(/[^\d]/g, '')}, Text ${i + 1}`);
                        console.log(`    标题信息: ${jsonData.partTitle || '未提取到标题'}`);
                        log(`数据已收集: Title ${target.title}, Part ${partText.replace(/[^\d]/g, '')}, Text ${i + 1}${jsonData.partTitle ? ', 标题: ' + jsonData.partTitle : ''}`, 'success');
                        
                        // 记录数据完整性
                        const dataFields = [
                          { name: '标题', value: jsonData.partTitle },
                          { name: '日期', value: jsonData.date },
                          { name: '摘要', value: jsonData.brief },
                          { name: 'PDF链接', value: jsonData.pdfUrl }
                        ];
                        
                        const missingFields = dataFields.filter(field => !field.value).map(field => field.name);
                        if (missingFields.length > 0) {
                          console.log(`    警告: 缺少字段 - ${missingFields.join(', ')}`);
                          log(`警告: 数据不完整，缺少 ${missingFields.join(', ')}`, 'warning');
                        }
                      } catch (dataError) {
                        console.error(`    创建或添加数据时出错: ${dataError.message}`);
                        log(`创建或添加数据时出错: ${dataError.message}`, 'error');
                      }
                      
                      // 关闭新标签页
                      await newPage.close();
                      console.log(`    新标签页已关闭`);
                      log('关闭新标签页', 'info');
                      
                    } catch (error) {
                      console.log(`    处理TEXT按钮时出错: ${error.message}`);
                      log(`处理TEXT按钮时出错: ${error.message}`, 'error');
                    }
                    
                    // 等待一下再处理下一个按钮
                    await page.waitForTimeout(2000);
                  }
                 
                 // 收起Part面板
                 console.log(`    收起Part ${partText.trim()}面板...`);
                 await partPanel.click();
                 await page.waitForTimeout(1000);
               } else {
                 console.log(`    Part ${partText.trim()}内容未能展开`);
               }
               
               try {
                 const resultObj = {
                   title: target.title,
                   part: partText.trim(),
                   partTitle: titleText, // 添加提取的标题
                   url: browsePath
                 };
                 results.push(resultObj);
                 console.log(`    添加到结果: Title ${target.title}, Part ${partText.trim()}, 标题: ${titleText || '未提取到标题'}`);
                 log(`添加结果: Part ${partText.trim()}${titleText ? ', 标题: ' + titleText : ''}`, 'info');
               } catch (error) {
                 console.error(`    添加结果时出错: ${error.message}`);
                 log(`添加结果时出错: ${error.message}`, 'error');
               }
             }
          }
        }
        
        // 收起面板
        await titleElement.click();
        await page.waitForTimeout(1000);
      } else {
        console.log(`未找到Title ${target.title}`);
      }
    }
    
    // 输出结果
    console.log('\n=== 搜索结果 ===');
    if (results.length > 0) {
      console.log(`找到 ${results.length} 个匹配的Part号码:\n`);
      
      // 按Title分组显示
      const groupedResults = {};
      results.forEach(result => {
        if (!groupedResults[result.title]) {
          groupedResults[result.title] = [];
        }
        groupedResults[result.title].push(result.part);
      });
      
      Object.keys(groupedResults).forEach(title => {
        console.log(`Title ${title}:`);
        groupedResults[title].forEach(part => {
          console.log(`  - ${part}`);
        });
        console.log('');
      });
    } else {
      console.log('未找到匹配的结果');
    }
    
    // 保存数据到文件，同时通过返回值传递给前端显示
    if (allData.length > 0) {
      console.log(`\n=== 所有数据已处理完成 ===`);
      console.log(`总共收集了 ${allData.length} 条数据`);
      log(`数据收集完成，总共收集了 ${allData.length} 条数据`);
      
      // 清理旧数据文件
      try {
          cleanupModuleData('govinfo');
      } catch (cleanupError) {
          log(`清理旧数据时出现警告: ${cleanupError.message}`, 'warning');
      }
      
      // 使用统一的数据路径管理
      const dataDir = pathUtils.getDataPath('govinfo');
      pathUtils.ensureDirectoryExists(dataDir);
      
      const filePath = path.join(dataDir, `govinfo_updates_${new Date().toISOString().slice(0, 10)}.json`);
      fs.writeFileSync(filePath, JSON.stringify(allData, null, 2));
      log(`数据已保存到文件: ${filePath}`, 'success');
      
      // 记录每个Title的数据数量
      const titleCounts = {};
      allData.forEach(item => {
        if (!titleCounts[item.title]) {
          titleCounts[item.title] = 0;
        }
        titleCounts[item.title]++;
      });
      
      // 记录每个Title的数据数量
      Object.keys(titleCounts).forEach(title => {
        log(`Title ${title}: 收集了 ${titleCounts[title]} 条数据`);
      });
    } else {
      log('未收集到任何数据');
      console.log('警告: allData为空数组');
    }
    
    console.log('返回数据到前端，数据长度:', allData.length);
    console.log('返回数据结构:', JSON.stringify({ success: true, data: allData.length }));
    return { success: true, data: allData };
    
  } catch (error) {
    console.error('\n=== 错误详情 ===');
    console.error('错误类型:', error.name);
    console.error('错误信息:', error.message);
    console.error('错误堆栈:', error.stack);
    
    // 提供故障排除建议
    if (error.message.includes('Timeout')) {
      console.error('\n故障排除建议:');
      console.error('1. 检查网络连接是否正常');
      console.error('2. 网站可能正在维护或响应缓慢');
      console.error('3. 尝试增加超时时间');
      console.error('4. 检查网站结构是否发生变化');
    }
    
    if (error.message.includes('选择器') || error.message.includes('元素')) {
      console.error('\n故障排除建议:');
      console.error('1. 网站页面结构可能已更改');
      console.error('2. 元素可能需要更长时间加载');
      console.error('3. 检查元素是否被其他内容遮挡');
    }
    
    // 网络错误处理
    if (error.message.includes('net::ERR_CERT_')) {
      console.error('\n故障排除建议:');
      console.error('1. HTTPS证书错误，已尝试忽略证书验证');
      console.error('2. 检查系统时间是否正确');
      console.error('3. 检查系统证书存储是否有问题');
    }
    
    if (error.message.includes('Failed to fetch') || error.message.includes('net::ERR_FAILED')) {
      console.error('\n故障排除建议:');
      console.error('1. 网络请求失败，可能是网络连接问题');
      console.error('2. 检查网络连接或代理设置');
      console.error('3. 目标网站可能暂时不可用');
      console.error('4. 尝试使用不同的浏览器或网络环境');
    }
    
    // 记录错误
    console.error(`搜索失败: ${error.message}`);
    // 如果有日志函数，则使用它记录错误
    if (typeof log === 'function') {
      log(`搜索失败: ${error.message}`, 'error');
    }
    
    // 截图用于调试 - 仅在控制台显示错误信息，不保存文件
    if (config.debug.screenshotOnError) {
      try {
        // 不再保存截图到文件，只记录错误信息
        console.error(`发生错误，无法继续执行: ${error.message}`);
        // 如果有日志函数，则使用它记录错误
        if (typeof log === 'function') {
          log(`发生错误，无法继续执行: ${error.message}`, 'error');
        }
      } catch (screenshotError) {
        console.error('处理错误截图失败:', screenshotError.message);
      }
    }
    
    return { success: false, error: error.message };
  } finally {
    // 关闭浏览器
    await browser.close();
    console.log('浏览器已关闭');
    log('浏览器已关闭，任务结束');
  }
}

async function runWithRetry(isHeadless, signal) {
  const maxRetries = config.retry.maxRetries;
  const baseRetryDelay = config.retry.retryDelay;
  let retryCount = 0;
  
  console.log(`配置的最大重试次数: ${maxRetries}, 基础重试延迟: ${baseRetryDelay}ms`);
  
  while (retryCount < maxRetries) {
    // 检查是否已经被中止
    if (signal && signal.aborted) {
      console.log('任务已被取消，停止重试');
      return { success: false, error: '任务已被用户取消' };
    }
    
    try {
      console.log(`尝试运行 (${retryCount + 1}/${maxRetries})...`);
      // 注意：selectedTimeframe已经在module.exports或runWithSignal中更新了config.website.timeframe
      const result = await scrapeCFRParts(isHeadless, signal);
      console.log('操作成功完成');
      return result;
    } catch (error) {
      retryCount++;
      console.error(`运行失败 (${retryCount}/${maxRetries}): ${error.message}`);
      console.error('错误类型:', error.name);
      console.error('错误堆栈:', error.stack);
      
      // 记录错误
      console.error(`尝试 ${retryCount}/${maxRetries} 失败: ${error.message}`);
      // 如果有日志函数，则使用它记录错误
      if (typeof log === 'function') {
        log(`尝试 ${retryCount}/${maxRetries} 失败: ${error.message}`, 'error');
      }
      
      // 针对特定错误类型提供更详细的诊断信息
      if (error.message.includes('net::ERR_CERT_')) {
        console.error('HTTPS证书错误，尝试忽略证书验证...');
      } else if (error.message.includes('Failed to fetch') || error.message.includes('net::ERR_FAILED')) {
        console.error('网络请求失败，可能是网络连接问题或目标网站不可用');
        console.error('建议检查网络连接或代理设置');
      }
      
      if (retryCount < maxRetries) {
        const waitTime = baseRetryDelay * retryCount; // 递增等待时间
        console.log(`等待 ${waitTime / 1000} 秒后重试...`);
        await new Promise(resolve => setTimeout(resolve, waitTime));
      } else {
        console.error('达到最大重试次数，放弃');
        return { 
          success: false, 
          error: `达到最大重试次数 (${maxRetries})，最后错误: ${error.message}`,
          errorDetails: {
            name: error.name,
            message: error.message,
            stack: error.stack
          }
        };
      }
    }
  }
}

// 支持中断信号的函数
async function runWithSignal(signal, isHeadless, selectedTimeframe) {
  try {
    // 检查信号是否已经被中止
    if (signal && signal.aborted) {
      console.log('任务已被取消');
      return { success: false, error: '任务已被用户取消' };
    }
    
    console.log('使用可中断模式启动任务...');
    
    // 如果提供了时间框架参数，则更新配置
    if (selectedTimeframe) {
      config.website.timeframe = selectedTimeframe;
      log(`使用用户选择的时间框架: ${selectedTimeframe}`, 'info');
    }
    
    // 直接调用 runWithRetry 并传递信号
    try {
      // 将信号传递给 runWithRetry
      const result = await runWithRetry(isHeadless, signal);
      return result;
    } catch (err) {
      // 检查是否是由于中断导致的错误
      if (signal && signal.aborted) {
        console.log('任务已被用户取消');
        return { success: false, error: '任务已被用户取消' };
      }
      
      // 其他错误
      throw err;
    }
  } catch (err) {
    console.error(`任务执行失败: ${err.stack || err}`);
    // 如果有日志函数，则使用它记录错误
    if (typeof log === 'function') {
      log(`任务执行失败: ${err.stack || err}`, 'error');
    }
    return { success: false, error: err.message || '任务执行失败' };
  }
}

// 导出主函数供外部调用
module.exports = async (isHeadless, selectedTimeframe) => {
  try {
    // 如果提供了时间框架参数，则更新配置
    if (selectedTimeframe) {
      config.website.timeframe = selectedTimeframe;
      log(`使用用户选择的时间框架: ${selectedTimeframe}`, 'info');
      console.log(`配置已更新，当前时间框架: ${config.website.timeframe}`);
    }
    
    // 调用 runWithRetry 方法并获取结果
    const result = await runWithRetry(isHeadless);
    
    // 返回处理结果
    return result;
  } catch (err) {
    console.error(`Main process failed: ${err.stack || err}`);
    // 如果有日志函数，则使用它记录错误
    if (typeof log === 'function') {
      log(`Main process failed: ${err.stack || err}`, 'error');
    }
    throw err;
  }
};

// 导出支持中断信号的函数
module.exports.runWithSignal = runWithSignal;